package com.nondo.rdp.finance.endpoint.api.app.course;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.nondo.rdp.auth.common.UserUtils;
import com.nondo.rdp.auth.domain.User;
import com.nondo.rdp.auth.endpoint.model.ConvertCall;
import com.nondo.rdp.auth.endpoint.model.Page;
import com.nondo.rdp.auth.endpoint.model.Query;
import com.nondo.rdp.core.common.StatusConstant;
import com.nondo.rdp.core.common.ValidateUtil;
import com.nondo.rdp.core.domain.attach.Attach;
import com.nondo.rdp.core.model.View;
import com.nondo.rdp.finance.common.OrderUtil;
import com.nondo.rdp.finance.domain.course.Course;
import com.nondo.rdp.finance.domain.course.CourseBuy;
import com.nondo.rdp.finance.domain.course.CourseRate;
import com.nondo.rdp.finance.domain.course.Section;
import com.nondo.rdp.finance.model.RequestPayBean;
import com.nondo.rdp.finance.model.Version;
import com.nondo.rdp.finance.model.course.CourseBean;
import com.nondo.rdp.finance.model.course.CourseQuery;
import com.nondo.rdp.finance.service.SettingService;
import com.nondo.rdp.finance.service.course.CourseBuyService;
import com.nondo.rdp.finance.service.course.CourseRateService;
import com.nondo.rdp.finance.service.course.CourseService;
import com.nondo.rdp.finance.service.course.SectionService;

@RestController("apiAppCourse")
@RequestMapping("/api/app/course")
public class CourseEndpoint {
    @Autowired
    CourseService courseService;
    
    @Autowired
    SectionService sectionService;
    
    @Autowired
    CourseRateService courseRateService;
    
    @Autowired
    CourseBuyService courseBuyService;
    
    @Autowired
    SettingService settingService;
    
    private static Logger _log = LoggerFactory.getLogger(CourseEndpoint.class);
    

    @RequestMapping("/info/{id}")
    public View<CourseBean> info(HttpServletRequest request, HttpServletResponse response, @PathVariable("id") Long id, @RequestBody Version version) {
        View<CourseBean> view = new View<CourseBean>(20000, "获取数据成功");

        CourseBean cousreBean = null;
        Course course = courseService.findOne(id);
        if (course != null) {
        	User user = UserUtils.checkUser();
            cousreBean = CourseBean.covert2Bean(course);
			if (user != null) {
				int isBuy = courseBuyService.getOne(id, user.getId());
				cousreBean.setIsBuy(isBuy);
			}
            cousreBean.setBuyButtonStatus(settingService.isHideBuyButton(version.getVno()));
        } else {
        	cousreBean = new CourseBean();
        }

        view.setData(cousreBean);
        
        return view;
    }

    @RequestMapping("/list")
    public View<Page<CourseQuery>> list(HttpServletRequest request, HttpServletResponse response, @RequestBody Query<Course> query) {
        View<Page<CourseQuery>> view = new View<Page<CourseQuery>>(20000, "获取列表成功");

        Course course = query.getData();

        Page<Course> page = courseService.findAll(new Page<Course>(query.getPage(), query.getSize()), course);
        
        Page<CourseQuery> resultPage = page.convertPage(new ConvertCall<Course, Page<CourseQuery>>() {

			@Override
			public Page<CourseQuery> execute(Page<Course> srcPage) {
				Page<CourseQuery> courseQueryPage = new Page<CourseQuery>(srcPage.getPageNumber(),srcPage.getPageSize(),srcPage.getTotalPages(),srcPage.getTotalElements());
				List<CourseQuery> courseQueryList = new ArrayList<CourseQuery>();
				List<Course> courseList = srcPage.getContent();
				for(Course course : courseList) {
					CourseQuery courseQuery = CourseQuery.covert2Bean(course);
					courseQueryList.add(courseQuery);
				}
				courseQueryPage.setContent(courseQueryList);
				return courseQueryPage;
			}
        	
		});

        view.setData(resultPage);

        return view;
    }
    
    @RequestMapping("/newList")
    public View<Map<String,Object>> newList(HttpServletRequest request, HttpServletResponse response) {
        View<Map<String,Object>> view = new View<Map<String,Object>>(20000, "获取列表成功");
        
        
        
        Map<String,Object> resultMap = new HashMap<String, Object>();
        
        //获取推荐专题课程列表
        List<CourseQuery> subjectList = getSubjectList();
        resultMap.put("subjectList", subjectList);
        
        //获取推荐普通课程列表
        List<CourseQuery> singleList = getSingleList();
        resultMap.put("singleList", singleList);
        
        //猜你喜欢课程列表
        List<CourseQuery> likeList = getLikeList();
        resultMap.put("likeList", likeList);
        
        view.setData(resultMap);

        return view;
    }

    //返回3条猜你喜欢课程
	private List<CourseQuery> getLikeList() {
		
		Query<Course> query = new Query<Course>();
        Course course = new Course();
		query.setPage(1);
        query.setSize(3);
        course.setType(0);
        
        List<CourseQuery> likeList = new ArrayList<CourseQuery>();
        Page<Course> page = courseService.findAll(new Page<Course>(query.getPage(), query.getSize()), course);
        
        page.convertPage(new ConvertCall<Course, Page<CourseQuery>>() {

			@Override
			public Page<CourseQuery> execute(Page<Course> srcPage) {
				Page<CourseQuery> courseQueryPage = new Page<CourseQuery>(srcPage.getPageNumber(),srcPage.getPageSize(),srcPage.getTotalPages(),srcPage.getTotalElements());
				
				List<Course> courseList = srcPage.getContent();
				for(Course course : courseList) {
					CourseQuery courseQuery = CourseQuery.covert2Bean(course);
					likeList.add(courseQuery);
				}
				courseQueryPage.setContent(likeList);
				return courseQueryPage;
			}
		});
		return likeList;
	}

	//返回4条推荐普通课程
	private List<CourseQuery> getSingleList() {
		
		Query<Course> query = new Query<Course>();
        Course course = new Course();
		query.setPage(1);
        query.setSize(4);
        course.setType(1);
        course.setRecommend(1);
        
        List<CourseQuery> singleList = new ArrayList<CourseQuery>();
        Page<Course> page = courseService.findAll(new Page<Course>(query.getPage(), query.getSize()), course);
        
        page.convertPage(new ConvertCall<Course, Page<CourseQuery>>() {

			@Override
			public Page<CourseQuery> execute(Page<Course> srcPage) {
				Page<CourseQuery> courseQueryPage = new Page<CourseQuery>(srcPage.getPageNumber(),srcPage.getPageSize(),srcPage.getTotalPages(),srcPage.getTotalElements());
				
				List<Course> courseList = srcPage.getContent();
				for(Course course : courseList) {
					CourseQuery courseQuery = CourseQuery.covert2Bean(course);
					List<Section> sectionList = sectionService.findByCourseId(course.getId());
					if(CollectionUtils.isNotEmpty(sectionList)){
						Section section = sectionList.get(0);
						courseQuery.setSid(section.getId());
						Attach video = section.getAttach();
						courseQuery.setVideoId(video.getVideoId());
					}
					singleList.add(courseQuery);
				}
				courseQueryPage.setContent(singleList);
				return courseQueryPage;
			}
		});
		return singleList;
	}

	//返回6条推荐专题课程
	private List<CourseQuery> getSubjectList() {
		
		Query<Course> query = new Query<Course>();
        Course course = new Course();
		query.setPage(1);
        query.setSize(6);
        course.setType(0);
        course.setRecommend(1);
        
        List<CourseQuery> subjectList = new ArrayList<CourseQuery>();
        Page<Course> page = courseService.findAll(new Page<Course>(query.getPage(), query.getSize()), course);
        
        page.convertPage(new ConvertCall<Course, Page<CourseQuery>>() {

			@Override
			public Page<CourseQuery> execute(Page<Course> srcPage) {
				Page<CourseQuery> courseQueryPage = new Page<CourseQuery>(srcPage.getPageNumber(),srcPage.getPageSize(),srcPage.getTotalPages(),srcPage.getTotalElements());
				
				List<Course> courseList = srcPage.getContent();
				for(Course course : courseList) {
					CourseQuery courseQuery = CourseQuery.covert2Bean(course);
					subjectList.add(courseQuery);
				}
				courseQueryPage.setContent(subjectList);
				return courseQueryPage;
			}
		});
		return subjectList;
	}

	/**
	 * 课程打分
	 * @param request
	 * @param response
	 * @param courseRate
	 * @return
	 */
    @RequestMapping("/rate")
    public View<CourseRate> rate(HttpServletRequest request, HttpServletResponse response, @Validated @RequestBody CourseRate courseRate) {
		View<CourseRate> view = new View<CourseRate>(20000, "打分成功");
		User user = UserUtils.getUser(request, response);
		Course course = this.courseService.findOne(courseRate.getCourseId());
		CourseRate courseRateDb = this.courseRateService.check(course.getId(),user.getId());
		if (courseRateDb != null) {
			view.setCode(3000);
			view.setMessage("您已经给该课程打过分啦");
			return view;
		}
		courseRate.setCourse(course);
		courseRate.setRateUser(user);
		this.courseRateService.save(courseRate);
		return view;
    }
    
    /**
     * 课程购买
     * @param request
     * @param response
     * @param course
     * @return
     */
    @SuppressWarnings("rawtypes")
	@RequestMapping("/buy")
    public View buy(HttpServletRequest request, HttpServletResponse response, @RequestBody Course course) {
		View view = new View(20000, "购买成功");
		
		User user = UserUtils.getUser(request, response);
		course = this.courseService.findOne(course.getId());
		if (course == null) {
			view.setCode(50000);
			view.setMessage("课程不存在或者已删除");
			return view;
		}
		int isBuy = this.courseBuyService.getOne(course.getId(), user.getId());
		if (isBuy == 0) {
			CourseBuy courseBuy = new CourseBuy();
			courseBuy.setCourse(course);
			courseBuy.setUser(user);
			this.courseBuyService.save(courseBuy);
		} else {
			view.setCode(50000);
			view.setMessage("用户已购买过此课程");
			return view;
		}
		
		return view;
    }
    
    /**
     * 课程下单
     * @param request
     * @param response
     * @param payBean
     * @param result
     * @return
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
	@RequestMapping("order")
    public View order(HttpServletRequest request, HttpServletResponse response, @Validated @RequestBody RequestPayBean payBean, BindingResult result) {
		View view = new View(20000, "下单成功");
		if (result.hasErrors()) {
			view.setCode(40000);
			view.setMessage(ValidateUtil.first(result.getAllErrors()));
			return view;
		}
		User user = UserUtils.getUser(request, response);
		Course course = this.courseService.findOne(payBean.getId());
		if (course == null) {
			view.setCode(30000);
			view.setMessage("课程不存在或者已删除");
			return view;
		}
		int isBuy = this.courseBuyService.getOne(course.getId(), user.getId());
		if (isBuy == 0) {
			//创建支付订单
			CourseBuy courseBuy = new CourseBuy();
			courseBuy.setCourse(course);
			courseBuy.setUser(user);
			Map retMap = this.courseBuyService.order(courseBuy, payBean);
			if (retMap == null) {
				view.setCode(30000);
				view.setMessage("支付中心下单验签失败");
				return view;
			}
			if("SUCCESS".equals(retMap.get("retCode")) && "SUCCESS".equalsIgnoreCase(retMap.get("resCode").toString())) {
				_log.info("下单成功：" + retMap);
				return view;
			}
			view.setCode(30000);
			view.setData(retMap);
			view.setMessage("下单失败");
			_log.error("下单失败：" + retMap);
		} else {
			view.setCode(30000);
			view.setMessage("用户已购买过此课程");
			return view;
		}
		
		return view;
    }
    
    /**
     * 支付完成通知
     * @param request
     * @param response
     * @return
     */
    @SuppressWarnings("rawtypes")
	@RequestMapping("/buyFinish")
    public View buyFinish(HttpServletRequest request, HttpServletResponse response) {
		View view = new View(20000, "购买成功");
		
		 _log.info("====== 开始处理支付中心通知 ======");
        Map<String,Object> paramMap = OrderUtil.request2payResponseMap(request, new String[]{
                "payOrderId","mchId","mchOrderNo","channelId","amount","currency","status", "clientIp",
                "device",  "subject", "channelOrderNo", "param1",
                "param2","paySuccTime","backType","sign"
        });
        _log.info("支付中心通知请求参数,paramMap={}", paramMap);
        if (!OrderUtil.verifyPayResponse(paramMap)) {
            String errorMessage = "verify request param failed.";
            _log.warn(errorMessage);
            view.setCode(30000);
			view.setMessage("请求参数不正确");
            return view;
        }
        String payOrderId = (String) paramMap.get("payOrderId");
        String mchOrderNo = (String) paramMap.get("mchOrderNo");
        String amount = (String) paramMap.get("amount");
        
		User user = UserUtils.getUser(request, response);
		
		CourseBuy courseBuy = this.courseBuyService.findByOrderNo(mchOrderNo);
		if (courseBuy == null) {
			_log.warn("业务订单不存在,payOrderId={},mchOrderNo={}", payOrderId,
					mchOrderNo);
			view.setCode(30000);
			view.setMessage("业务订单不存在");
			return view;
		}
		if (!user.getId().equals(courseBuy.getUser().getId())) {
			_log.warn("业务订单与当前登录人不匹配,payOrderId={},mchOrderNo={}", payOrderId,
					mchOrderNo);
			view.setCode(30000);
			view.setMessage("业务订单与当前登录人不匹配");
			return view;
		}
		if (courseBuy.getAmount() != Float.parseFloat(amount)) {
			 _log.warn("支付金额不一致,dbPayPrice={},payPrice={}", courseBuy.getAmount(), amount);
			 view.setCode(30000);
			view.setMessage("支付金额不一致");
		}
		Course course = courseBuy.getCourse();
		int isBuy = this.courseBuyService.getOne(course.getId(), user.getId());
		if (isBuy == 0) {
			//更新业务订单状态
			courseBuy.setStatus(1);
			this.courseBuyService.update(courseBuy);
		} else {
			view.setCode(30000);
			view.setMessage("用户已购买过此课程");
			return view;
		}
		
		return view;
    }
    
    /**
     * 已购课程列表
     * @param request
     * @param response
     * @param query
     * @return
     */
    @RequestMapping("/buy/list")
    public View<Page<CourseQuery>> buyList(HttpServletRequest request, HttpServletResponse response, @RequestBody Query<Course> query) {
        View<Page<CourseQuery>> view = new View<Page<CourseQuery>>(20000, "获取列表成功");

        Course course = query.getData();

        User user = UserUtils.getUser(request, response);
        
		if (course == null) {
			course = new Course();
		}
		
		// 课程发布者只能查询自己购买的课程
		int payFinish = StatusConstant.COURSE_PAY_SUCCESS;
		course.setStatus(payFinish);
		course.setUser(user);

        Page<CourseBuy> page = courseBuyService.findAll(new Page<CourseBuy>(query.getPage(), query.getSize()), course);
        
        Page<CourseQuery> resultPage = page.convertPage(new ConvertCall<CourseBuy, Page<CourseQuery>>() {

			@Override
			public Page<CourseQuery> execute(Page<CourseBuy> srcPage) {
				Page<CourseQuery> courseQueryPage = new Page<CourseQuery>(srcPage.getPageNumber(),srcPage.getPageSize(),srcPage.getTotalPages(),srcPage.getTotalElements());
				List<CourseQuery> courseQueryList = new ArrayList<CourseQuery>();
				List<CourseBuy> courseBuyList = srcPage.getContent();
				for(CourseBuy courseBuy : courseBuyList) {
					Course course = courseService.findOne(courseBuy.getCourse().getId());
					CourseQuery courseQuery = CourseQuery.covert2Bean(course);
					courseQueryList.add(courseQuery);
				}
				courseQueryPage.setContent(courseQueryList);
				return courseQueryPage;
			}
        	
		});

        view.setData(resultPage);

        return view;
    }
    
    /**
     * 课程分类列表查询
     * @param request
     * @param response
     * @param query
     * @return
     */
    @RequestMapping("/listByClassify")
    public View<Page<CourseQuery>> listByClassify(HttpServletRequest request, HttpServletResponse response, @RequestBody Query<Course> query) {
        View<Page<CourseQuery>> view = new View<Page<CourseQuery>>(20000, "获取列表成功");

        Course course = query.getData();

        Page<Course> page = courseService.findAll(new Page<Course>(query.getPage(), query.getSize()), course);
        
        Page<CourseQuery> resultPage = page.convertPage(new ConvertCall<Course, Page<CourseQuery>>() {

			@Override
			public Page<CourseQuery> execute(Page<Course> srcPage) {
				Page<CourseQuery> courseQueryPage = new Page<CourseQuery>(srcPage.getPageNumber(),srcPage.getPageSize(),srcPage.getTotalPages(),srcPage.getTotalElements());
				List<CourseQuery> courseQueryList = new ArrayList<CourseQuery>();
				List<Course> courseList = srcPage.getContent();
				for(Course course : courseList) {
					CourseQuery courseQuery = CourseQuery.covert2Bean(course);
					if (course.getType() == 1) {
						List<Section> sectionList = sectionService
								.findByCourseId(course.getId());
						if (CollectionUtils.isNotEmpty(sectionList)) {
							Section section = sectionList.get(0);
							courseQuery.setSid(section.getId());
							Attach video = section.getAttach();
							courseQuery.setVideoId(video.getVideoId());
						}
					}
					courseQueryList.add(courseQuery);
				}
				courseQueryPage.setContent(courseQueryList);
				return courseQueryPage;
			}
        	
		});

        view.setData(resultPage);

        return view;
    }
    
}